/**
 * @brief 用于进行项目源代码的阶段性测试
 */
#include "../logger.hpp"
#include "../utils.hpp"
#include <cassert>  // 测试用

void test_logger()
{
    LOG_INIT(false, DEBUG, 512); // 1. 输出到控制台，最低日志级别为DEBUG
    LOG(DEBUG, "This is a debug message\n");    // 测试DEBUG日志
    LOG(INFO, "This is an info message\n");     // 测试INFO日志
    LOG(ERROR, "This is an error message\n");   // 测试ERROR日志

    LOG_INIT(false, ERROR, 512); // 2. 输出到控制台，最低日志级别为ERROR
    LOG(DEBUG, "This debug message should not appear\n");
    LOG(INFO, "This info message should not appear\n");
    LOG(ERROR, "This error message should appear\n");

    LOG_INIT(true, DEBUG, 512); // 3. 输出到文件，最低日志级别为DEBUG
    LOG(DEBUG, "Logging to file\n");
    LOG(INFO, "Another log entry\n");

    // 4. 检查文件内容
    std::ifstream log_file("log.txt\n");
    std::string line;
    bool found_debug = false;
    bool found_info = false;
    while (std::getline(log_file, line)) {
        if (line.find("Logging to file") != std::string::npos) {
            found_debug = true;
        }
        if (line.find("Another log entry") != std::string::npos) {
            found_info = true;
        }
    }
    // 程序崩溃表示测试成功
    assert(found_debug && "Debug message not found in log file");
    assert(found_info && "Info message not found in log file");

    // 5. 关闭并清理日志文件
    log_file.close();
    std::remove("log.txt");
}

#define HOST "127.0.0.1"
#define USER "root"
#define PASSWD "1257"
#define DBNAME "learning"
#define PORT 3306

void test_mysql_util() {
    MYSQL *mysql = mysql_util::mysql_create(HOST, USER, PASSWD, DBNAME, PORT);
    const std::string s1 = "insert into `student` values (NULL, '张三', 18, 13, 82, 43);";
    const std::string s2 = "insert into `student` values (NULL, '李四', 18, 16, 73, 18);";
    const std::string s3 = "insert into `student` values (NULL, '王五', 18, 51, 45, 83);";
    mysql_util::mysql_execute(mysql, s1);
    mysql_util::mysql_execute(mysql, s2);
    mysql_util::mysql_execute(mysql, s3);
    const std::string u1 = "update student set Chinese=Chinese+20 where name='张三';";
    const std::string u2 = "update student set age=20 where name='李四';";
    const std::string u3 = "update student set name='赵六' where name='王五';";
    // mysql_util::mysql_execute(mysql, u1);
    // mysql_util::mysql_execute(mysql, u2);
    // mysql_util::mysql_execute(mysql, u3);
    const std::string d1 = "delete from student;";
    // mysql_util::mysql_execute(mysql, d1);   
    const std::string s = "select * from `student`;";
    mysql_util::mysql_execute(mysql, s); 

    MYSQL_RES *result = mysql_store_result(mysql);
    if (result == nullptr) {
        mysql_close(mysql);
        return ;
    }

    uint64_t row_size = mysql_num_rows(result);
    unsigned int col_size = mysql_num_fields(result);
    for (int i = 0; i < row_size; i++) {
        MYSQL_ROW row = mysql_fetch_row(result);    // 这个获取其实类似于row = arr++, arr是数组首地址
        for (int j = 0; j < col_size; j++) {
            std::cout << row[j] << "\t";
        }
        std::cout << std::endl;
    }
    mysql_free_result(result);
    mysql_util::mysql_destroy(mysql);
}

void test_json_util() {
    Json::Value man;
    man["name"] = "Alice";
    man["age"] = 18;
    man["is_student"] = true;
    man["score"].append(88);
    man["score"].append(66.7);
    man["score"].append(99.6);

    std::string json_string;
    if (json_util::serialize(man, json_string) == false) {
        return ;
    }
    else std::cout << "-----serialize result-----\n";
    std::cout << json_string << std::endl;

    Json::Value result;
    if (json_util::deserialize(json_string, result) == false) {
        return ;
    }
    std::cout << "-----deserialize result-----\n";
    std::cout << result["name"] << std::endl;
    std::cout << result["age"] << std::endl;
    std::cout << result["score"][0] << ", " 
              << result["score"][1] << ", " 
              << result["score"][2] << std::endl;
}

void test_string_util() {
    {
        // 测试正常分割
        std::string src = "hello,world,test";
        std::string sep = ",";
        std::vector<std::string> res;
        int count = string_util::split(src, sep, res);
        assert(count == 3);
        assert(res.size() == 3);
        assert(res[0] == "hello");
        assert(res[1] == "world");
        assert(res[2] == "test");
    }

    {
        // 测试空字符串
        std::string src = "";
        std::string sep = ",";
        std::vector<std::string> res;
        int count = string_util::split(src, sep, res);
        assert(count == 0);
        assert(res.empty());
    }

    {
        // 测试空分隔符
        std::string src = "test";
        std::string sep = "";
        std::vector<std::string> res;
        int count = string_util::split(src, sep, res);
        assert(count == -1); // 期望返回 -1
    }

    {
        // 测试分隔符在开头
        std::string src = ",test,example";
        std::string sep = ",";
        std::vector<std::string> res;
        int count = string_util::split(src, sep, res);
        assert(count == 2);
        assert(res[0] == "test");
        assert(res[1] == "example");
    }

    {
        // 测试分隔符在结尾
        std::string src = "test,example,";
        std::string sep = ",";
        std::vector<std::string> res;
        int count = string_util::split(src, sep, res);
        assert(count == 2);
        assert(res[0] == "test");
        assert(res[1] == "example");
    }
}

void test_file_util() {
    {
        // 测试读取正常文件
        std::string filename = "test.txt"; // 确保这个文件存在
        std::ofstream out(filename, std::ios::out);
        out << "hello world";
        out.close();
        std::string content;
        bool result = file_util::read(filename, content);
        assert(result == true); // 读取成功
        assert(!content.empty()); // 内容不为空
        out.close();
        std::remove("test.txt");
        LOG(DEBUG, "读取正常文件测试通过\n");
    }

    {
        // 测试读取不存在的文件
        std::string filename = "non_existent_file.txt"; // 确保这个文件不存在
        std::string content;
        bool result = file_util::read(filename, content);
        assert(result == false); // 读取失败
        assert(content.empty()); // 内容应该为空
        LOG(DEBUG, "读取不存在文件测试通过\n");
    }

    {
        // 测试读取空文件
        std::ofstream out("empty.txt", std::ios::out);
        std::string filename = "empty.txt"; // 确保这个文件是空的
        std::string content;
        bool result = file_util::read(filename, content);
        assert(result == true); // 读取成功
        assert(content.empty()); // 内容应该为空
        out.close();
        std::remove("empty.txt");
        LOG(DEBUG, "读取空文件测试通过\n");
    }
}

// 探索更高效构建SQL语句的方法——已弃用
std::string sql(Json::Value &user) {
    std::ostringstream sqlStream;
    sqlStream << "insert into `user` values(null, '"
            << user["username"].asCString() << "', password('" 
            << user["password"].asCString() << "'), 1000, 0, 0);";
    return sqlStream.str();
}

#include "../data_manager.hpp"
void test_class_user_table() {
    Json::Value user;
    user["username"] = "xiaohong";
    user["password"] = "123123";
    user_table ut_hdl(HOST, USER, PASSWD, "gomoku", PORT);
    if (ut_hdl.register_user(user)) {
        LOG(DEBUG, "注册成功\n");
    }
    if (ut_hdl.authenticate_user_login(user)) {
        LOG(DEBUG, "登录成功\n");
    }
    if (ut_hdl.find_user_by_username("xiaohong", user)) {
        LOG(DEBUG, "username查找成功\n");
    }
    if (ut_hdl.find_user_by_uid(1, user)) {
        LOG(DEBUG, "uid查找成功\n");
    }
    if (ut_hdl.update_win_user_score(1)) {
        LOG(DEBUG, "对战胜利\n");
    }
    if (ut_hdl.update_win_user_score(1)) {
        LOG(DEBUG, "对战胜利\n");
    }
    if (ut_hdl.update_fail_user_score(1)) {
        LOG(DEBUG, "对战失败\n");
    }
}

#include "../online_manager.hpp"

void test_class_online_manager() {
    online_manager online_mgr;
    asio_wssvr_t::connection_ptr conn;
    uint32_t uid = 1;
    online_mgr.enter_game_hall(uid, conn);
    if (online_mgr.is_in_game_hall(uid)) {
        LOG(DEBUG, "在游戏大厅\n");
    } else {
        LOG(DEBUG, "不在游戏大厅\n");
    }
    online_mgr.exit_game_hall(uid, conn);
    if (online_mgr.is_in_game_hall(uid)) {
        LOG(DEBUG, "在游戏大厅\n");
    } else {
        LOG(DEBUG, "不在游戏大厅\n");
    }

    online_mgr.enter_game_room(uid, conn);
    if (online_mgr.is_in_game_room(uid)) {
        LOG(DEBUG, "在游戏房间\n");
    } else {
        LOG(DEBUG, "不在游戏房间\n");
    }
    online_mgr.exit_game_room(uid, conn);
    if (online_mgr.is_in_game_room(uid)) {
        LOG(DEBUG, "在游戏房间\n");
    } else {
        LOG(DEBUG, "不在游戏房间\n");
    }
}

int main()
{
    LOG_INIT(false, DEBUG, 512);
    // test_logger();
    // test_mysql_util();
    // test_json_util();
    // test_string_util();
    // test_file_util();
    // test_class_user_table();
    test_class_online_manager();
    return 0;
}